import { useState, useEffect, useMemo } from "react";
import { Form, Skeleton, Grid, ErrorBlock, Tabs } from 'antd-mobile';
import { PieOutline, FrownOutline, GiftOutline } from 'antd-mobile-icons';
import { PortraitAnalysisTitle } from './PortraitAnalysisTitle';
import { useWindowSize } from "@uidotdev/usehooks";
import { Explain } from './Explain';
import { Mix, measureTextWidth, G2, Sunburst } from '@ant-design/plots';
import { MindMapGraph } from '@ant-design/graphs';
import { useSelector, useDispatch } from 'react-redux';
import { fetchReq } from '../slices/questionsSlice';

function ReqGraph({ data, subjects }) {
    console.log(JSON.stringify(data));

    const mindConfig = useMemo(() => {
        const width = 120;
        const nodeSize = [width, 20];

        const transformData = (arr) => {
            const grouped = arr.reduce((acc, cur) => {
                if (!acc[cur.category]) {
                    acc[cur.category] = {};
                }

                if (!acc[cur.category][cur.university]) {
                    acc[cur.category][cur.university] = [];
                }

                acc[cur.category][cur.university].push(cur);

                return acc;
            }, {});

            const result = {
                id: 'A0',
                value: {
                    title: '可选专业',
                    items: [{ text: subjects }],
                },
                children: [],
            };

            for (let category in grouped) {
                const categoryNode = {
                    id: category,
                    value: {
                        title: category,
                        items: [{ text: '专业（类）名称' }],
                    },
                    children: [],
                };

                for (let university in grouped[category]) {
                    let item = grouped[category][university][0];
                    const universityNode = {
                        id: item.id.toString(),
                        value: {
                            title: university,
                            items: [{ text: item['level'] || '院校名称', tag: item['province'] }],
                        },
                        children: [],
                    };

                    const majors = item.majors.split('、').filter(Boolean);
                    universityNode.children = majors.map(major => ({
                        id: item.id + "_" + major,
                        value: {
                            title: major,
                            items: [{ text: "专业" }],
                        }
                    }));

                    categoryNode.children.push(universityNode);
                }

                result.children.push(categoryNode);
            }

            return result;
        };
        return {
            data: transformData(data),
            markerCfg: (cfg) => {
                const { children = [], id } = cfg;
                if (id === 'A0') {
                    return [
                        {
                            position: 'left',
                            show: !!children?.length,
                        },
                        {
                            position: 'right',
                            show: !!children?.length,
                        },
                    ];
                }
                return {
                    position: 'right',
                    show: !!children?.length,
                };
            },
            behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'],
            layout: {
                getHeight: () => {
                    return 20;
                },
            },
            minimapCfg: {
                show: true,
                type: 'delegate',
                refresh: true,
                padding: 20
            },
            nodeCfg: {
                autoWidth: true,
                padding: 4,
                size: nodeSize,
                style: {
                    stroke: '#5AD8A6',
                },
                items: {
                    padding: [4, 0],
                },
                customContent: (item, group, cfg) => {
                    const { startX, startY } = cfg;
                    const { text, tag } = item;
                    const tagWidth = 28;
                    const tagHeight = 16;
                    group?.addShape('rect', {
                        attrs: {
                            x: 0,
                            y: 0,
                            width: nodeSize[0],
                            height: nodeSize[1] + 8,
                            fillOpacity: 0.1,
                        },
                        // group 内唯一字段
                        name: `container-${Math.random()}`,
                    });
                    if (tag) {
                        group?.addShape('rect', {
                            attrs: {
                                x: startX,
                                y: startY,
                                width: tagWidth,
                                height: tagHeight,
                                fill: '#47c796',
                            },
                            // group 内唯一字段
                            name: `tag-${Math.random()}`,
                        });
                        group?.addShape('text', {
                            attrs: {
                                textBaseline: 'middle',
                                textAlign: 'center',
                                x: startX + tagWidth / 2,
                                y: startY + tagHeight / 2,
                                text: tag,
                                fill: '#fff',
                                fontSize: 10,
                            },
                            // group 内唯一字段
                            name: `text-${Math.random()}`,
                        });
                        group?.addShape('text', {
                            attrs: {
                                textBaseline: 'middle',
                                textAlign: 'start',
                                x: startX + tagWidth + 4,
                                y: startY + tagHeight / 2,
                                text: text,
                                fill: 'rgba(0,0,0,.65)',
                                fontSize: 10,
                            },
                            // group 内唯一字段
                            name: `text-${Math.random()}`,
                        });
                    } else {
                        group?.addShape('text', {
                            attrs: {
                                textBaseline: 'middle',
                                textAlign: 'start',
                                x: startX,
                                y: startY + tagHeight / 2,
                                text: text,
                                fill: 'rgba(0,0,0,.65)',
                                fontSize: 10,
                            },
                            // group 内唯一字段
                            name: `text-${Math.random()}`,
                        });
                    }

                },
            }
        };
    }, [data, subjects]);
    const sunConfig = useMemo(() => {
        function transformData(data) {
            const result = [];

            data.forEach(item => {
                let categoryObj = result.find(e => e.label === item.category);
                if (!categoryObj) {
                    categoryObj = { label: item.category, children: [], sum: 0 };
                    result.push(categoryObj);
                }

                let universityObj = categoryObj.children.find(e => e.label === item.university);
                if (!universityObj) {
                    universityObj = { label: `${item.university}`, children: [], sum: 0 };
                    categoryObj.children.push(universityObj);
                }

                item.majors.split("、").forEach(major => {
                    let majorObj = universityObj.children.find(e => e.label === major);
                    if (!majorObj) {
                        majorObj = { label: major, children: [], sum: 1 };
                        universityObj.children.push(majorObj);
                        universityObj.sum += majorObj.sum;
                    }
                });

                categoryObj.sum += universityObj.sum;
            });

            return result;
        }
        return {
            data: {
                "label": subjects,
                "children": transformData(data)
            },
            innerRadius: 0.2,
            radius: 1,
            interactions: [
                {
                    type: 'element-active',
                },
            ],
            hierarchyConfig: {
                field: 'sum',
            },
            label: {
                layout: [
                    {
                        type: 'limit-in-shape',
                    },
                ],
            },
        };
    }, [data, subjects]);
    console.log(sunConfig);
    return <>
        <PortraitAnalysisTitle
            text={"数据来自2024年最新数据，"}
            explainLabelStyle={{ textDecoration: "underline", color: "#229880", cursor: "pointer" }}
            explainLabel={"联系我们获得更详细数据"}
            speed={10}
        ></PortraitAnalysisTitle>
        <Tabs>
            <Tabs.Tab title='知识图谱' key='mind'>
                <MindMapGraph {...mindConfig} />
            </Tabs.Tab>
            <Tabs.Tab title='旭日图' key='rose'>
                <Sunburst {...sunConfig} />
            </Tabs.Tab>
        </Tabs>
    </>;
};

export function SubjectSelectionRecommendations({ advise, explain }) {
    function abbreviate(subject) {
        return subject[0] + subject[2] + subject[4];
    }
    function renderStatistic(containerWidth, text, style) {
        const { width: textWidth, height: textHeight } = measureTextWidth(text, style);
        const R = containerWidth / 2; // r^2 = (w / 2)^2 + (h - offsetY)^2
        let scale = 1;
        if (containerWidth < textWidth) {
            scale = Math.min(Math.sqrt(Math.abs(Math.pow(R, 2) / (Math.pow(textWidth / 2, 2) + Math.pow(textHeight, 2)))), 1);
        }
        const textStyleStr = `width:${containerWidth}px;`;
        return `<div style="${textStyleStr};font-size:${scale}em;line-height:${scale < 1 ? 1 : 'inherit'};">${text}</div>`;
    }
    const dispatch = useDispatch();
    const [loading, setLoading] = useState(false);
    const [reqLoading, setReqLoading] = useState(false);

    const [currSubjects, setCurrSubjects] = useState(undefined);
    const req = useSelector(state => state.questions.present.req);
    useEffect(() => {
        let timeout;
        async function _fetchReq() {
            setReqLoading(true);
            if (currSubjects) {
                await dispatch(fetchReq(currSubjects?.originLabel));
                timeout = setTimeout(() => setReqLoading(false), 1000);
            }
        }
        _fetchReq();
        return () => clearTimeout(timeout);
    }, [currSubjects, dispatch]);

    const data = useMemo(() => advise?.split(',').map(item => {
        const matches = item.match(/^([\u4e00-\u9fa5]{6})\((\d+)\)$/); // Match 6 Chinese characters followed by score
        if (matches) {
            return {
                "originLabel": matches[1],
                "label": abbreviate(matches[1]),
                "score": parseInt(matches[2])
            };
        }
        return null;
    }).filter(Boolean).slice(0, 7), [advise]);
    G2.registerInteraction('ssr-active-element', {
        start: [
            {
                trigger: 'element:click',
                action: (context) => setCurrSubjects(context?.event?.data?.data),
            },
        ],
    });
    const config = useMemo(() => {
        if (data && data.length > 0) {
            setCurrSubjects(data[0]);
            return {
                tooltip: false,
                legend: true,
                plots: [
                    {
                        type: 'pie',
                        region: {
                            start: {
                                x: 0,
                                y: 0,
                            },
                            end: {
                                x: 1,
                                y: 0.75,
                            },
                        },
                        options: {
                            data,
                            colorField: 'label',
                            angleField: 'score',
                            radius: 1,
                            appendPadding: 10,
                            startAngle: Math.PI * 0.2,
                            endAngle: Math.PI * (0.2 + 2 * data.length / 7),
                            pieStyle: {
                                lineWidth: 0,
                            },
                            innerRadius: 0.3,
                            statistic: {
                                title: {
                                    style: {
                                        fontSize: '20px',
                                    },
                                    customHtml: (container, view, datum) => {
                                        const { width, height } = container.getBoundingClientRect();
                                        const d = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(height / 2, 2));
                                        const text = datum ? datum.label : '';
                                        return renderStatistic(d, text, {});
                                    },
                                },
                                content: {
                                    offsetX: 10,
                                    offsetY: 5,
                                    style: {
                                        fontSize: '18px',
                                    },
                                    customHtml: (container, view, datum, data) => {
                                        const { width } = container.getBoundingClientRect();
                                        const text = datum ? `${datum.score}` : ``;
                                        return renderStatistic(width, text, {});
                                    },
                                },
                            },
                            label: {
                                type: 'inner',
                                content: '{name} {value}',
                                style: {
                                    fontSize: 13,
                                },
                            },
                            interactions: [
                                {
                                    type: 'pie-statistic-active',
                                },
                                {
                                    type: 'association-highlight',
                                },
                                {
                                    type: 'ssr-active-element',
                                }
                            ],
                        }
                    },
                    {
                        type: 'column',
                        region: {
                            start: {
                                x: 0,
                                y: 0.8,
                            },
                            end: {
                                x: 1,
                                y: 1,
                            },
                        },
                        options: {
                            data,
                            xField: 'label',
                            yField: 'score',
                            seriesField: 'label',
                            label: {
                                position: 'middle',
                                style: {
                                    fill: '#FFFFFF',
                                    opacity: 0.6,
                                },
                            },
                            xAxis: {
                                label: false
                            },
                            interactions: [
                                {
                                    type: 'element-highlight',
                                },
                                {
                                    type: 'association-highlight',
                                },
                                {
                                    type: 'ssr-active-element',
                                }
                            ],
                        }
                    }
                ]
            };
        }
        return {};
    }, [data]);
    const [explainVisible, setExplainVisible] = useState(false);
    const { width: windowWidth, } = useWindowSize();
    const chartsColumn = useMemo(() => windowWidth < 700 ? 1 : 2, [windowWidth]);
    const chartsSpan = useMemo(() => (chartsColumn === 2 && !explainVisible) ? 2 : 1, [chartsColumn, explainVisible]);
    useEffect(() => {
        let timeout;
        function init() {
            setLoading(true);
            if (advise) {
                timeout = setTimeout(() => {
                    setLoading(false);
                    setExplainVisible(true);
                }, 1000);
            }
        }
        init();
        return () => clearTimeout(timeout);
    }, [advise]);
    return advise &&
        <>
            <Form.Item
                label={loading ? "" : <>
                    <PieOutline color='#000' />&nbsp;
                    <PortraitAnalysisTitle
                        text={"我的学科建议。"}
                        explainLabelStyle={{ textDecoration: "underline", color: "#229880", cursor: "pointer" }}
                        explainLabel={advise ? (explainVisible ? "收起解释" : "解释此建议") : ""}
                        onClickExplain={() => setExplainVisible(!explainVisible)}
                        speed={10}
                    >
                    </PortraitAnalysisTitle>
                </>}
            >
                {loading ?
                    <>
                        <Skeleton.Title animated />
                        <Skeleton.Paragraph lineCount={7} animated />
                    </>
                    :
                    (
                        data && data.length > 0 ?
                            <>
                                <Grid columns={chartsColumn} gap={8}>
                                    {config && <Grid.Item span={chartsSpan}>
                                        <Mix {...config} />
                                    </Grid.Item>}
                                    {explainVisible && <Grid.Item style={{ paddingTop: "10%" }}>
                                        <Explain data={{ status: 'success', explain }}></Explain>
                                    </Grid.Item>}
                                </Grid>
                            </>
                            :
                            <>
                                <ErrorBlock status='default' description={<span>
                                    <FrownOutline color='#000' />
                                    发生了未知错误。
                                </span>} />
                            </>
                    )}
            </Form.Item>
            {
                currSubjects &&
                <Form.Item
                    label={<>
                        <GiftOutline color='#000' />&nbsp;
                        <PortraitAnalysisTitle
                            text={"如果您选择："}
                            explainLabelStyle={{ textDecoration: "underline", color: "#229880", cursor: "pointer" }}
                            explainLabel={currSubjects?.label}
                            speed={50}
                        ></PortraitAnalysisTitle>
                    </>}
                >
                    {reqLoading ?
                        <>
                            <Skeleton.Title animated />
                            <Skeleton.Paragraph lineCount={7} animated />
                        </>
                        :
                        req?.data && req?.data.length > 0 && <>
                            <ReqGraph data={req?.data} subjects={currSubjects?.label} ></ReqGraph>
                        </>
                    }
                </Form.Item>
            }
        </>;
}
